package com.lh.utils;

import com.lh.entity.table.DeadlineNode;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

public class DeadlineNodeStatistics {

    /**
     * 按部门分组并计算统计数据
     * @param deadlineNodes 原始DeadlineNode列表
     * @return 按部门统计的结果数组
     */
    public static List<Map<String, Object>> groupByDepartment(List<DeadlineNode> deadlineNodes) {
        // 1. 按部门分组（优先使用departmentName，为空时用realDepartment）
        Map<String, List<DeadlineNode>> departmentGroups = deadlineNodes.stream()
                .collect(Collectors.groupingBy(node -> {
                    String deptName = node.getDepartmentName();
                    // 部门名称为空时，使用realDepartment作为分组依据
                    return deptName != null && !deptName.isEmpty() ? deptName : node.getRealDepartment();
                }));

        // 2. 遍历每个部门，计算统计数据
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<String, List<DeadlineNode>> entry : departmentGroups.entrySet()) {
            String department = entry.getKey();
            List<DeadlineNode> nodes = entry.getValue();

            // 计算红、黄、绿数量
            int red = 0;
            int yellow = 0;
            int green = 0;

            for (DeadlineNode node : nodes) {
                String warnLevel = node.getWarnLevel();
                // 预警级别：0=绿色，1=黄色，2=红色（兼容字符串或数字格式）
                if ("2".equals(warnLevel) || "red".equalsIgnoreCase(warnLevel)) {
                    red++;
                } else if ("1".equals(warnLevel) || "yellow".equalsIgnoreCase(warnLevel)) {
                    yellow++;
                } else if ("0".equals(warnLevel) || "green".equalsIgnoreCase(warnLevel)) {
                    green++;
                }else{
                    green++;
                }
            }

            // 计算总数
            int total = nodes.size();

            // 计算红灯率（保留两位小数）
            String rate = "0.00%";
            if (total > 0) {
                BigDecimal redBig = new BigDecimal(red);
                BigDecimal totalBig = new BigDecimal(total);
                BigDecimal rateBig = redBig.divide(totalBig, 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal(100))
                        .setScale(2, RoundingMode.HALF_UP);
                rate = rateBig + "%";
            }

            // 构建统计结果对象
            Map<String, Object> stat = new HashMap<>();
            stat.put("red", red);
            stat.put("yellow", yellow);
            stat.put("green", green);
            stat.put("total", total);
            stat.put("rate", rate);
            stat.put("rateSort", calculateRateSort(rate)); // 按红灯率排序的权重
            stat.put("street", department); // 部门名称作为street字段

            result.add(stat);
        }

        return result;
    }

    /**
     * 计算红灯率排序权重（用于排序，数值越大优先级越高）
     * @param rate 红灯率字符串（如"50.00%"）
     * @return 排序权重
     */
    private static int calculateRateSort(String rate) {
        try {
            // 提取数字部分并转换为整数（如"50.00%" → 50）
            String rateNum = rate.replace("%", "");
            BigDecimal rateBig = new BigDecimal(rateNum);
            return rateBig.setScale(0, RoundingMode.HALF_UP).intValue();
        } catch (Exception e) {
            return 0;
        }
    }


    /**
     * 将统计结果Map列表转换为DeadlineNode列表
     * @param statistics 统计结果Map列表
     * @return 转换后的DeadlineNode列表
     */
    public static List<DeadlineNode> convertToDeadlineNodes(List<Map<String, Object>> statistics) {
        List<DeadlineNode> nodes = new ArrayList<>();
        if (statistics == null || statistics.isEmpty()) {
            return nodes;
        }

        for (Map<String, Object> stat : statistics) {
            DeadlineNode node = new DeadlineNode();

            // 设置红黄绿数量
            node.setRed(convertToInt(stat.get("red")));
            node.setYellow(convertToInt(stat.get("yellow")));
            node.setGreen(convertToInt(stat.get("green")));
            node.setTotal(convertToInt(stat.get("total")));

            // 设置红灯率相关字段
            node.setRate(convertToString(stat.get("rate")));
            node.setRateSort(convertToInt(stat.get("rateSort")));

            // 设置部门名称（street对应部门）
            node.setDepartmentName(convertToString(stat.get("street")));
            node.setStreet(convertToString(stat.get("street")));
            node.setRealDepartment(convertToString(stat.get("street"))); // 同时设置realDepartment

            nodes.add(node);
        }

        return nodes;
    }

    /**
     * 将DeadlineNode列表按rate（红灯率）从低到高排序
     * @param nodes 待排序的DeadlineNode列表
     * @return 排序后的列表
     */
    public static List<DeadlineNode> sortByRateAsc(List<DeadlineNode> nodes) {
        if (nodes == null || nodes.isEmpty()) {
            return new ArrayList<>();
        }

        // 按rate字段数值从低到高排序
        nodes.sort(Comparator.comparingDouble(node -> {
            String rate = node.getRate();
            if (rate == null || !rate.contains("%")) {
                return 0.0; // 无效格式视为0%
            }
            try {
                // 提取百分比数值（如"50.00%" -> 50.00）
                String rateNum = rate.replace("%", "").trim();
                return new BigDecimal(rateNum).doubleValue();
            } catch (Exception e) {
                return 0.0; // 转换失败视为0%
            }
        }));

        return nodes;
    }

    // 辅助方法：将Object转换为Integer（处理null和类型转换）
    private static Integer convertToInt(Object value) {
        if (value == null) {
            return 0;
        }
        if (value instanceof Integer) {
            return (Integer) value;
        }
        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        return 0;
    }

    // 辅助方法：将Object转换为String（处理null）
    private static String convertToString(Object value) {
        if (value == null) {
            return "";
        }
        return value.toString().trim();
    }


}
